﻿using ExDUIR.NET.Declaration;

namespace ExDUIR.NET.Handle
{
    // 基类用于IntPtr类型的句柄
    public abstract class ExHandleIntPtr : IDisposable
    {
        protected IntPtr handle;

        public IntPtr Handle => handle;

        public bool IsInvalid => handle == IntPtr.Zero;

        protected ExHandleIntPtr(IntPtr handle)
        {
            this.handle = handle;
        }

        public abstract bool Release();

        public void Dispose()
        {
            Release();
            GC.SuppressFinalize(this);
        }

        ~ExHandleIntPtr()
        {
            Release();
        }
    }

    // 基类用于int类型的句柄
    public abstract class ExHandleInt : IDisposable
    {
        protected int handle;

        public int Handle => handle;

        public bool IsInvalid => handle == 0;

        protected ExHandleInt(int handle)
        {
            this.handle = handle;
        }

        public abstract bool Release();

        public void Dispose()
        {
            Release();
            GC.SuppressFinalize(this);
        }

        ~ExHandleInt()
        {
            Release();
        }
    }

    // 具体句柄类实现
    public sealed class ExResourceHandle : ExHandleIntPtr
    {
        public ExResourceHandle(IntPtr handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI.Ex_ResFree(handle);
                if (result) handle = IntPtr.Zero;
                return result;
            }
            return false;
        }
    }

    public sealed class ExEasingHandle : ExHandleIntPtr
    {
        public ExEasingHandle(IntPtr handle) : base(handle) { }

        public override bool Release()
        {
            return true;
        }
    }

    public sealed class ExThemeHandle : ExHandleIntPtr
    {
        public ExThemeHandle(IntPtr handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI.Ex_ThemeFree(handle);
                if (result) handle = IntPtr.Zero;
                return result;
            }
            return false;
        }
    }

    public sealed class ExSkinHandle : ExHandleInt
    {
        public ExSkinHandle(int handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI.Ex_ObjDestroy(handle);
                if (result) handle = 0;
                return result;
            }
            return false;
        }
    }

    public sealed class ExControlHandle : ExHandleInt
    {
        public ExControlHandle(int handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI.Ex_ObjDestroy(handle);
                if (result) handle = 0;
                return result;
            }
            return false;
        }
    }

    public sealed class ExBrushHandle : ExHandleIntPtr
    {
        public ExBrushHandle(IntPtr handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI._brush_destroy(handle);
                if (result) handle = IntPtr.Zero;
                return result;
            }
            return false;
        }
    }

    public sealed class ExImageHandle : ExHandleInt
    {
        public ExImageHandle(int handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI._img_destroy(handle);
                if (result) handle = 0;
                return result;
            }
            return false;
        }
    }

    public sealed class ExImageListHandle : ExHandleIntPtr
    {
        public ExImageListHandle(IntPtr handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI._imglist_destroy(handle);
                if (result) handle = IntPtr.Zero;
                return result;
            }
            return false;
        }
    }

    public sealed class ExFontHandle : ExHandleInt
    {
        public ExFontHandle(int handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI._font_destroy(handle);
                if (result) handle = 0;
                return result;
            }
            return false;
        }
    }

    public sealed class ExPathHandle : ExHandleInt
    {
        public ExPathHandle(int handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI._path_destroy(handle);
                if (result) handle = 0;
                return result;
            }
            return false;
        }
    }

    public sealed class ExRegionHandle : ExHandleIntPtr
    {
        public ExRegionHandle(IntPtr handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI._rgn_destroy(handle);
                if (result) handle = IntPtr.Zero;
                return result;
            }
            return false;
        }
    }

    public sealed class ExMatrixHandle : ExHandleIntPtr
    {
        public ExMatrixHandle(IntPtr handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI._matrix_destroy(handle);
                if (result) handle = IntPtr.Zero;
                return result;
            }
            return false;
        }
    }

    public sealed class ExLayoutHandle : ExHandleInt
    {
        public ExLayoutHandle(int handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI._layout_destroy(handle);
                if (result) handle = 0;
                return result;
            }
            return false;
        }
    }

    public sealed class ExCanvasHandle : ExHandleInt
    {
        public ExCanvasHandle(int handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = ExAPI._canvas_destroy(handle);
                if (result) handle = 0;
                return result;
            }
            return false;
        }
    }

    public sealed class ExCursorHandle : ExHandleIntPtr
    {
        public ExCursorHandle(IntPtr handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = WinAPI.DestroyCursor(handle);
                if (result) handle = IntPtr.Zero;
                return result;
            }
            return false;
        }
    }

    public sealed class ExIconHandle : ExHandleIntPtr
    {
        public ExIconHandle(IntPtr handle) : base(handle) { }

        public override bool Release()
        {
            if (!IsInvalid)
            {
                bool result = WinAPI.DestroyIcon(handle);
                if (result) handle = IntPtr.Zero;
                return result;
            }
            return false;
        }
    }
}
